﻿package com.gengine.keyBoard
{
    import com.gengine.global.*;
    import com.mui.controls.*;
    import fl.controls.*;
    import flash.display.*;
    import flash.events.*;
    import flash.system.*;
    import flash.text.*;
    import flash.utils.*;

    public class KeyBoardManager extends EventDispatcher
    {
        private var _changeImeFlase:int;
        private var _tempKeyCode:uint = 0;
        private var _isDispatchEvent:Boolean = false;
        public static const ALTKEYCHANGE:String = "altKeyChange";
        private static var _keyMap:Object = {};
        private static var _instance:KeyBoardManager;
        private static var _stage:Stage;
        public static var ctrlKey:Boolean;
        public static var ShiftKey:Boolean;
        public static var AltKey:Boolean;

        public function KeyBoardManager()
        {
            if (_instance != null)
            {
                throw new Error("KeyBoardManager 不能实例化");
            }
            _instance = this;
            return;
        }// end function

        public function start() : void
        {
            _stage = Global.stage;
            if (_stage)
            {
                this.addListener();
            }
            return;
        }// end function

        public function cancelListener() : void
        {
            if (_stage)
            {
                _stage.removeEventListener(KeyboardEvent.KEY_DOWN, this.onKeyDownHandler);
                _stage.removeEventListener(KeyboardEvent.KEY_UP, this.onKeyUpHandler);
                _stage.removeEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, this.onMouseFocusChangeHandler);
            }
            return;
        }// end function

        public function addListener() : void
        {
            if (_stage)
            {
                _stage.addEventListener(KeyboardEvent.KEY_DOWN, this.onKeyDownHandler, false, 9999, false);
                _stage.addEventListener(KeyboardEvent.KEY_UP, this.onKeyUpHandler, false, 9999, false);
                _stage.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, this.onMouseFocusChangeHandler, false, 9999, false);
                _stage.addEventListener(Event.ACTIVATE, this.onActivateHandler, false, 9999, false);
            }
            return;
        }// end function

        private function onActivateHandler(event:Event) : void
        {
            _stage.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDownHandler, true, 9999, false);
            return;
        }// end function

        private function onMouseLeaveHandler(event:Event) : void
        {
            _stage.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDownHandler, true, 9999, false);
            return;
        }// end function

        private function onMouseFocusChangeHandler(event:FocusEvent) : void
        {
            if (event.relatedObject is TextField)
            {
                if ((event.relatedObject as TextField).type == TextFieldType.INPUT)
                {
                    this.changeImeEnable(true);
                }
                else
                {
                    _stage.focus = _stage;
                    this.clearT();
                    setTimeout(this.changeImeFlase, 200);
                }
            }
            else if (event.relatedObject is TextInput)
            {
                this.changeImeEnable(true);
            }
            else if (event.relatedObject is BaseButton)
            {
                _stage.focus = _stage;
                this.changeImeEnable(false);
            }
            else
            {
                _stage.focus = _stage;
                this.changeImeEnable(false);
            }
            return;
        }// end function

        private function clearT() : void
        {
            if (this._changeImeFlase)
            {
                clearTimeout(this._changeImeFlase);
                this._changeImeFlase = 0;
            }
            return;
        }// end function

        private function changeImeFlase() : void
        {
            var _loc_1:* = Global.stage.focus;
            if (_loc_1 is TextInput || _loc_1 is TextField && (_loc_1 as TextField).type == TextFieldType.INPUT)
            {
                return;
            }
            if (Capabilities.hasIME)
            {
                try
                {
                    IME.enabled = false;
                }
                catch (e:Error)
                {
                }
            }
            return;
        }// end function

        public function changeImeEnable(param1:Boolean) : void
        {
            if (param1 == IME.enabled)
            {
                return;
            }
            if (Capabilities.hasIME)
            {
                try
                {
                    IME.enabled = param1;
                }
                catch (e:Error)
                {
                }
            }
            return;
        }// end function

        private function onMouseDownHandler(event:MouseEvent) : void
        {
            if (ctrlKey != event.ctrlKey)
            {
                ctrlKey = event.ctrlKey;
                if (event.ctrlKey)
                {
                    this.dispatchKeyDownEvent(KeyCode.CONTROL, this.getKeyboardEvent(KeyboardEvent.KEY_UP, KeyCode.CONTROL));
                }
                else
                {
                    this.dispatchKeyUpEvent(KeyCode.CONTROL, this.getKeyboardEvent(KeyboardEvent.KEY_DOWN, KeyCode.CONTROL));
                }
            }
            if (ShiftKey != event.shiftKey)
            {
                ShiftKey = event.shiftKey;
                if (event.shiftKey)
                {
                    this.dispatchKeyDownEvent(KeyCode.SHIFT, this.getKeyboardEvent(KeyboardEvent.KEY_UP, KeyCode.SHIFT));
                }
                else
                {
                    this.dispatchKeyUpEvent(KeyCode.SHIFT, this.getKeyboardEvent(KeyboardEvent.KEY_DOWN, KeyCode.SHIFT));
                }
            }
            _stage.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDownHandler);
            return;
        }// end function

        private function onKeyDownHandler(event:KeyboardEvent) : void
        {
            if (Alert.alertWinList.length > 0 && Alert.mode != Alert.Mode_NoneNotModal)
            {
                Alert.flick(Alert.alertWinList[0]);
                return;
            }
            ctrlKey = event.ctrlKey;
            ShiftKey = event.shiftKey;
            if (this._tempKeyCode == event.keyCode)
            {
                return;
            }
            this._tempKeyCode = event.keyCode;
            if (event.keyCode == KeyCode.ALT)
            {
                AltKey = true;
                this.dispatchEvent(new Event(ALTKEYCHANGE));
            }
            if (event.keyCode == KeyCode.CONTROL)
            {
                ctrlKey = true;
                this.dispatchKeyDownEvent(KeyCode.CONTROL, event);
            }
            else if (event.keyCode == KeyCode.SHIFT)
            {
                ShiftKey = true;
                this.dispatchKeyDownEvent(KeyCode.SHIFT, event);
            }
            else
            {
                this.dispatchKeyDownEvent(event.keyCode, event, ShiftKey, ctrlKey);
            }
            event.stopImmediatePropagation();
            return;
        }// end function

        private function onKeyUpHandler(event:KeyboardEvent) : void
        {
            if (this._tempKeyCode == event.keyCode)
            {
                this._tempKeyCode = 0;
            }
            if (event.keyCode == KeyCode.ALT)
            {
                AltKey = false;
                this.dispatchEvent(new Event(ALTKEYCHANGE));
            }
            if (event.keyCode == KeyCode.CONTROL)
            {
                ctrlKey = false;
                this.dispatchKeyUpEvent(KeyCode.CONTROL, event);
            }
            else if (event.keyCode == KeyCode.SHIFT)
            {
                ShiftKey = false;
                this.dispatchKeyUpEvent(KeyCode.SHIFT, event);
            }
            else
            {
                this.dispatchKeyUpEvent(event.keyCode, event, ShiftKey);
            }
            event.stopImmediatePropagation();
            return;
        }// end function

        private function dispatchKeyUpEvent(param1:int, param2:KeyboardEvent = null, param3:Boolean = false) : void
        {
            var _loc_4:* = createKeyData(param1, param3);
            var _loc_5:* = new KeyEvent(KeyEvent.KEY_UP, _loc_4);
            _loc_5.keyEvent = param2;
            dispatchEvent(_loc_5);
            return;
        }// end function

        private function dispatchKeyDownEvent(param1:int, param2:KeyboardEvent = null, param3:Boolean = false, param4:Boolean = false) : void
        {
            var _loc_5:* = createKeyData(param1, param3, param4);
            var _loc_6:* = new KeyEvent(KeyEvent.KEY_DOWN, _loc_5);
            _loc_6.keyEvent = param2;
            dispatchEvent(_loc_6);
            return;
        }// end function

        private function getKeyboardEvent(param1:String, param2:uint) : KeyboardEvent
        {
            return new KeyboardEvent(param1, true, false, 0, param2, 0, ctrlKey, false, ShiftKey);
        }// end function

        public static function get instance() : KeyBoardManager
        {
            if (_instance == null)
            {
                _instance = new KeyBoardManager;
            }
            return _instance;
        }// end function

        public static function addkeys(param1:Array) : void
        {
            var _loc_3:KeyData = null;
            if (param1 == null || param1.length == 0)
            {
                return;
            }
            if (param1[0] as KeyData == null)
            {
                throw new Error("addkeys(value:Array) value中不是KeyData类型");
            }
            var _loc_2:* = param1.length;
            var _loc_4:int = 0;
            while (_loc_4 < _loc_2)
            {
                
                _loc_3 = param1[_loc_4] as KeyData;
                _keyMap[_loc_3.keyCode] = _loc_3;
                _loc_4++;
            }
            return;
        }// end function

        public static function createKeyData(param1:uint, param2:Boolean = false, param3:Boolean = false) : KeyData
        {
            var _loc_4:* = getKeyData(param1, param2, param3);
            if (_loc_4 == null)
            {
                _loc_4 = new KeyData(param1, param2, param3);
                _loc_4.isKeyDown = false;
                _keyMap[_loc_4.key] = _loc_4;
            }
            return _loc_4;
        }// end function

        public static function getKeyData(param1:uint, param2:Boolean = false, param3:Boolean = false) : KeyData
        {
            if (param2)
            {
                param1 = param1 + KeyCode.SHIFT_NUM;
            }
            else if (param3)
            {
                param1 = param1 + KeyCode.CTRL;
            }
            return _keyMap[param1];
        }// end function

    }
}
